////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-2017 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxentry.cpp
/// @brief CamX HAL3 Entry Points
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "camxentry.h"
#include "camxhal3.h"
#include "camxincs.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Dispatch::Dispatch
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Dispatch::Dispatch(
    VOID* pAPIJumpTable)
    : m_pJumpTable(pAPIJumpTable)
{
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Dispatch::GetJumpTableHAL3
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID* Dispatch::GetJumpTable()
{
    VOID* pJumpTable = NULL;

    // Ensure a consistent pointer value is read
#if _LP64
    CAMX_STATIC_ASSERT(sizeof(VOID*) == sizeof(UINT64));
    pJumpTable = reinterpret_cast<VOID*>(CamxAtomicLoadU64(reinterpret_cast<UINT64*>(&m_pJumpTable)));
#elif _WIN64
    CAMX_STATIC_ASSERT(sizeof(VOID*) == sizeof(UINT64));
    pJumpTable = reinterpret_cast<VOID*>(CamxAtomicLoadU64(reinterpret_cast<UINT64*>(&m_pJumpTable)));
#else
    CAMX_STATIC_ASSERT(sizeof(VOID*) == sizeof(UINT32));
    pJumpTable = reinterpret_cast<VOID*>(CamxAtomicLoadU32(reinterpret_cast<UINT32*>(&m_pJumpTable)));
#endif // _LP64

    CAMX_ASSERT(NULL != pJumpTable);

    return pJumpTable;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Dispatch::SetJumpTableHAL3
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID Dispatch::SetJumpTable(
    VOID* pJumpTable)
{
    // Ensure a consistent pointer value is written
#if _LP64
    CAMX_STATIC_ASSERT(sizeof(VOID*) == sizeof(UINT64));
    CamxAtomicStoreU64(reinterpret_cast<UINT64*>(&m_pJumpTable), reinterpret_cast<UINT64>(pJumpTable));
#elif _WIN64
    CAMX_STATIC_ASSERT(sizeof(VOID*) == sizeof(UINT64));
    CamxAtomicStoreU64(reinterpret_cast<UINT64*>(&m_pJumpTable), reinterpret_cast<UINT64>(pJumpTable));
#else
    CAMX_STATIC_ASSERT(sizeof(VOID*) == sizeof(UINT32));
    CamxAtomicStoreU32(reinterpret_cast<UINT32*>(&m_pJumpTable), reinterpret_cast<UINT32>(pJumpTable));
#endif // _LP64
}

CAMX_NAMESPACE_END
